#include "stm32f10x.h"
#include "timer.h"
#include "bsp_led.h"
#include "delay.h"
#include "tjc_usart_hmi.h"
#include "stdbool.h"
#include "bsp_adc.h"
#include "bsp_dac.h "
#include "AD9834.h"
#include <math.h>
// ADC1转换的电压值通过MDA方式传到SRAM
extern __IO uint32_t ADC_ConvertedValue;
extern u32 count1;
// 局部变量，用于保存转换计算后的电压值
uint32_t ADC_ConvertedValueLocal[300] = {0};
uint32_t ADC_Vpplist[500] = {0}; // 接收数据的长度
#define FRAMELENGTH 4
#define SWEEP_POINTS 500

float maxing=0;
float VOUT=0;
void NVIC_Configuration(void);
void RCC_Configuration(void);
u32 SweepMinFre = 100;	  // 最小频率
u32 SweepMaxFre = 500000; // 最大频率（改为500000Hz）
u32 SweepStepFre = 200;	  // 步进
float SweepTime = 0.5;	  // 扫频时间ms 0.5的时候是1秒 1的时候是2秒  1.5的时候是3秒 2的时候是4秒 2.5的时候是5秒
u16 sweepIndex = 0;		  // 当前扫频点索引
u8 SweepFlag = 0;		  // 扫频标志位
u8 signalOK = 0;
int err=0;
// int ms=1;//扫频时间换算值
bool mode = 0; // 点频和扫频模式的切换 0 - 点频模式  1 - 扫频模式
int freq1, freq2, v1, v2,w1,w2;
u32 V, Freq,W;
// 输入信号峰峰值（单位：V），根据实际信号源调整
#define INPUT_VPP 0.038

const int table_data[30][11] = {
    {437, 447, 455, 464, 471, 479, 485, 492, 498, 504, 509},   // 原428->437
    {392, 401, 409, 417, 426, 432, 439, 445, 451, 456, 461},   // 原383->392
    {382, 393, 401, 409, 416, 424, 430, 436, 442, 447, 453},   // 原373->382
    {384, 393, 402, 410, 417, 425, 430, 437, 443, 448, 453},   // 原375->384
    {389, 397, 406, 414, 422, 429, 436, 442, 447, 453, 459},   // 原380->389
    {395, 404, 412, 421, 428, 435, 442, 448, 454, 460, 464},   // 原386->395
    {404, 413, 421, 430, 437, 444, 449, 455, 461, 467, 472},   // 原395->404
    {409, 418, 427, 436, 443, 450, 457, 463, 469, 475, 480},   // 原400->409
    {417, 426, 434, 443, 451, 458, 465, 471, 477, 483, 488},   // 原408->417
    {425, 434, 443, 453, 459, 466, 473, 480, 486, 491, 497},   // 原416->425
    {432, 442, 450, 459, 466, 474, 481, 487, 493, 500, 505},   // 原423->432
    {439, 448, 457, 466, 474, 481, 488, 495, 501, 508, 513},   // 原430->439
    {447, 455, 464, 473, 480, 488, 496, 502, 509, 515, 521},   // 原438->447
    {453, 462, 471, 480, 488, 495, 503, 509, 516, 523, 529},   // 原444->453
    {459, 468, 477, 486, 494, 502, 509, 517, 523, 530, 536},   // 原450->459
    {466, 475, 484, 493, 501, 509, 517, 524, 531, 537, 544},   // 原457->466
    {472, 482, 491, 501, 508, 516, 524, 531, 538, 545, 551},   // 原463->472
    {478, 488, 497, 506, 515, 523, 531, 538, 545, 552, 558},   // 原469->478
    {484, 495, 504, 513, 521, 530, 538, 545, 552, 559, 566},   // 原475->484
    {491, 501, 510, 520, 529, 537, 545, 552, 559, 567, 574},   // 原482->491
    {497, 506, 516, 527, 535, 543, 551, 559, 566, 574, 582},   // 原488->497
    {503, 513, 522, 533, 543, 550, 559, 566, 574, 581, 589},   // 原494->503
    {508, 519, 529, 539, 548, 557, 565, 573, 581, 588, 596},   // 原499->508
    {514, 525, 535, 545, 555, 563, 572, 580, 588, 596, 603},   // 原505->514
    {520, 530, 541, 551, 561, 570, 579, 587, 595, 603, 611},   // 原511->520
    {526, 537, 547, 558, 567, 577, 585, 594, 603, 610, 619},   // 原517->526
    {532, 543, 554, 563, 573, 583, 592, 601, 609, 617, 627},   // 原523->532
    {537, 549, 559, 570, 580, 590, 599, 608, 616, 625, 634},   // 原528->537
    {543, 554, 565, 576, 586, 596, 605, 615, 624, 632, 641},   // 原534->543
    {552, 563, 575, 585, 596, 606, 613, 623, 632, 641, 650}    // 原543->552
};
void protol(void);
void sweepstep(void);
void filtertype(uint32_t arr[], int len);
void set_amplitude_frequency(double Vout, uint32_t freq);
void get_table_value(uint8_t u1, uint8_t u2);

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

	// 嵌套向量中断控制器组选择
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	// 配置USART为中断源
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	// 抢断优先级
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	// 子优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	// 使能中断
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	// 初始化配置NVIC
	NVIC_Init(&NVIC_InitStructure);
}

void RCC_Configuration(void)
{ // RCC时钟的设置
	ErrorStatus HSEStartUpStatus;
	RCC_DeInit();								/* RCC system reset(for debug purpose) RCC寄存器恢复初始化值*/
	RCC_HSEConfig(RCC_HSE_ON);					/* Enable HSE 使能外部高速晶振*/
	HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* Wait till HSE is ready 等待外部高速晶振使能完成*/
	if (HSEStartUpStatus == SUCCESS)
	{
		/*设置PLL时钟源及倍频系数*/
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // RCC_PLLMul_x（枚举2~16）是倍频值。当HSE=8MHZ,RCC_PLLMul_9时PLLCLK=72MHZ
		/*设置AHB时钟（HCLK）*/
		RCC_HCLKConfig(RCC_SYSCLK_Div1); // RCC_SYSCLK_Div1——AHB时钟 = 系统时钟(SYSCLK) = 72MHZ（外部晶振8HMZ）
		/*注意此处的设置，如果使用SYSTICK做延时程序，此时SYSTICK(Cortex System timer)=HCLK/8=9MHZ*/
		RCC_PCLK1Config(RCC_HCLK_Div2); // 设置低速AHB时钟（PCLK1）,RCC_HCLK_Div2——APB1时钟 = HCLK/2 = 36MHZ（外部晶振8HMZ）
		RCC_PCLK2Config(RCC_HCLK_Div1); // 设置高速AHB时钟（PCLK2）,RCC_HCLK_Div1——APB2时钟 = HCLK = 72MHZ（外部晶振8HMZ）
		/*注：AHB主要负责外部存储器时钟。APB2负责AD，I/O，高级TIM，串口1。APB1负责DA，USB，SPI，I2C，CAN，串口2，3，4，5，普通TIM */
		FLASH_SetLatency(FLASH_Latency_2); // 设置FLASH存储器延时时钟周期数
		/*FLASH时序延迟几个周期，等待总线同步操作。
		推荐按照单片机系统运行频率：
		0—24MHz时，取Latency_0；
		24—48MHz时，取Latency_1；
		48~72MHz时，取Latency_2*/
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // 选择FLASH预取指缓存的模式，预取指缓存使能
		RCC_PLLCmd(ENABLE);									  // 使能PLL
		while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
			;									   // 等待PLL输出稳定
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 选择SYSCLK时钟源为PLL
		while (RCC_GetSYSCLKSource() != 0x08)
			; // 等待PLL成为SYSCLK时钟源
	}
	/*开始使能程序中需要使用的外设时钟*/
	//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE); //APB2外设时钟使能
	//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	//	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
}

int main(void)
{
	RCC_Configuration();
	NVIC_Configuration();
	delay_init(72);
	delay_ms(300);
	// Timerx_Init(99, 71);//这里设置为10ms进一次中断
	LED_GPIO_Config();
	USART1_Init(115200);
	Dac1_Init();
	Dac1_Set_Vol(2000);
	ADCx_Init();
	//  TJCPrintf("t666.txt=\"666\"\xff\xff\xff"); // 确保串口HMI正常通信
	AD9834_Init();
	AD9834_Select_Wave(Sine_Wave);
	AD9834_Set_Freq(FREQ_0, 1000);
	while (1)
	{
		// 读取转换的AD值

		if (mode == 1) // 扫频模式开灯
		{
			// TJCPrintf("t666.txt=\"888\"\xff\xff\xff"); // 确保串口HMI正常通信
			LED1_ON;
			LED3_OFF;
			sweepstep();
			filtertype(ADC_Vpplist, 500);
		}
		if (mode == 0) // 点频模式关灯
		{

			//	ADC_Converted[count1] = (uint32_t)ADC_ConvertedValue;
			protol();
			LED1_OFF;
			LED3_ON;
		}

		//		ADC_ConvertedValueLocal =(float) ADC_ConvertedValue[1]/4096*3.3; // 读取转换的AD值
	}
}

// 执行单步扫频
void sweepstep(void)
{
	if (mode != 1)
		return;
	// 对数等间隔频率点
	double ratio = (double)SweepMaxFre / SweepMinFre;
	double log_step = log(ratio) / (SWEEP_POINTS - 1);
	u32 currentFreq = (u32)(SweepMinFre * exp(log_step * sweepIndex));

	// 设置频率
	AD9834_Set_Freq(FREQ_0, currentFreq);
	// TJCPrintf("t666.txt=\"899\"\xff\xff\xff"); // 确保串口HMI正常通信

	// 短暂延时确保信号稳定
	delay_ms(10);

	// 循环读取200个ADC的值
	for (int i = 0; i < 300; i++)
	{
		delay_us(200);
		ADC_ConvertedValueLocal[i] = ADC_ConvertedValue; // 替换为您的ADC读取函数
		//TJCPrintf("%d",ADC_ConvertedValueLocal[i]);
	}
	uint32_t max = ADC_ConvertedValueLocal[0];
	for (int i = 1; i < 300; i++)
	{
		if (ADC_ConvertedValueLocal[i] > max)
		{
			max = ADC_ConvertedValueLocal[i];
		} 
	}
	uint32_t min = ADC_ConvertedValueLocal[0];
	for (int i = 1; i < 300; i++)
	{
		if (ADC_ConvertedValueLocal[i] < min)
		{
			min = ADC_ConvertedValueLocal[i];
		} 
	}
	
	ADC_Vpplist[sweepIndex] = max - min; // 将ADC值转换为电压值
	TJCPrintf("%d", ADC_Vpplist[sweepIndex]);
	//  移动到下一个点
	sweepIndex++;
	delay_ms(5);

	// 检查是否完成
	if (sweepIndex >= SWEEP_POINTS)
	{
		SweepFlag = 1;
		mode = 0; // 返回点频模式
		sweepIndex = 0;
	}
}

void protol(void)
{
 // LED2_ON;
	while (usize >= FRAMELENGTH)
	{
		// JCPrintf("t666.txt=\"111\"\xff\xff\xff");

		// 进行解析
		if (usize >= FRAMELENGTH && u(0) == 0x55)
		{

			if (u(1) == 0x01)
			{
				// SweepTime += 0.5;
			}
			else if (u(1) == 0x15)
			{
				// SweepTime -= 0.5;
				SweepFlag = 0;
			}
			else if (u(1) == 0x21)
			{
				if (mode == 0)
				{
					mode = 1;
				}
			}
			else if (u(1) == 0x28)
			{
				if (mode == 1)
				{
					mode = 0;
				}
			}
			else if (u(1) == 0x19)
			{
				TJCPrintf("t666.txt=\"222\"\xff\xff\xff");
				freq1 = u(2);
				freq2 = u(3);
				Freq = (freq2 << 8) | freq1;
				AD9834_Select_Wave(Sine_Wave);
				AD9834_Set_Freq(FREQ_0, Freq * 100);
				delay_ms(10);
			}
			else if (u(1) == 0x18)
			{
				TJCPrintf("t666.txt=\"inputing\"\xff\xff\xff");
				v1 = u(2);
				v2 = u(3);
				V = (v2 << 8) | v1;
				Dac1_Set_Vol(V);
				// LED1_ON;
				delay_ms(100);
				TJCPrintf("t666.txt=\"ready\"\xff\xff\xff");
				// LED1_OFF;
			}
			else if (u(1) == 0x20)
			{
				if (SweepFlag == 1)
				{
					int haha=0;
					for (int j = 0; j < 400; j++)
					{
						float ww=ADC_Vpplist[j]/maxing;
						float tt=180*(1 -ww);
						uint32_t ttt=tt;
						TJCPrintf("line %d,%d,%d,%d,RED\xff\xff\xff", 10 + j, 220, 10 + j, ttt);
						//TJCPrintf("%d",220 - ADC_Maxlist[j] * 0.2);
						delay_ms(1);
					}
					for (int j = 400; j < 500; j += 2)
					{
            haha++;
						float ww=ADC_Vpplist[j]/maxing;
						float tt=180*(1 -ww);
						uint32_t ttt=tt;
						TJCPrintf("line %d,%d,%d,%d,RED\xff\xff\xff", 409+haha, 220, 409+haha, ttt);
						//TJCPrintf("%d",220 - ADC_Maxlist[j] * 0.2);
						delay_ms(1);
					}
				}
			}
			else if (u(1) == 0x66)
			{
				
					get_table_value(u(2),u(3));
			}
			else if (u(1) == 0x78){
				LED2_ON;
				err=0;
				if(u(2)==0x11){
				  err=err+u(3);
				}
				if(u(2)==0x12){
				  err=err-u(3);
				}
			  delay_ms(100);
				LED2_OFF	;			
			}
		}
		udelete(FRAMELENGTH);
	}
	//LED2_OFF;
}

void filtertype(uint32_t arr[], int len){
	if (SweepFlag != 1)
		return;
	// 1. 找出最大值
	uint32_t max_val = arr[0];
	for (int i = 1; i < len; i++)        
	{
		if (arr[i] > max_val)
		{
			max_val = arr[i];
		}
	}
	maxing=max_val ;

	// 2. 设置阈值 (最大值的70.7%)
	uint32_t threshold = (uint32_t)(max_val * 0.707f + 0.5f); // 四舍五入

	// 3. 检测阈值穿越点
	int cross_count = 0;					 // 穿越次数
	int cross_points[10] = {0};				 // 存储穿越点位置
	bool prev_state = (arr[0] >= threshold); // 初始状态

	for (int i = 1; i < len; i++)
	{
		bool current_state = (arr[i] >= threshold);

		// 检测状态变化（阈值穿越）
		if (current_state != prev_state)
		{
			if (cross_count < 10)
			{ // 防止数组越界
				cross_points[cross_count++] = i;
			}
			prev_state = current_state;
		}
	}

	// 4. 判断滤波器类型
	if (cross_count == 0)
	{
		// 无穿越点：全通或全阻
		if (arr[0] >= threshold)
		{
			TJCPrintf("t1111.txt=\"1\"\xff\xff\xff"); // 低通(全通)
		}
		else
		{
			TJCPrintf("t1111.txt=\"2\"\xff\xff\xff"); // 高通(全阻)
		}
	}
	else if (cross_count == 1)
	{
		// 单次穿越
		if (arr[0] >= threshold)
		{
			TJCPrintf("t1111.txt=\"1\"\xff\xff\xff"); // 低通
		}
		else
		{
			TJCPrintf("t1111.txt=\"2\"\xff\xff\xff"); // 高通
		}
	}
	else
	{
		// 两次或多次穿越（取前两次）
		int start = cross_points[0];
		int end = (cross_count >= 2) ? cross_points[1] : cross_points[0];

		// 计算中间区域的平均值
		uint32_t mid_sum = 0;
		int count = 0;
		for (int i = start; i < end; i++)
		{
			mid_sum += arr[i];
			count++;
		}
		uint32_t mid_avg = (count > 0) ? mid_sum / count : 0;

		if (mid_avg >= threshold)
		{
			TJCPrintf("t1111.txt=\"3\"\xff\xff\xff"); // 带通
		}
		else
		{
			TJCPrintf("t1111.txt=\"4\"\xff\xff\xff"); // 带阻
		}
	}
}

/**
 * @brief 根据串口数据获取表格值
 * @param u1 列索引（十六进制，范围0x01~0x0B）
 * @param u2 行索引（十六进制，范围0x01~0x1E）
 * @return 对应的表格值，索引错误返回-1
 */
void get_table_value(uint8_t u1, uint8_t u2) {
    // 验证列索引 (1~11)
	  int tv=0;
    if(u1 < 0x01 || u1 > 0x0B) {
        //return -1;  // 无效列索引
    }
    
    // 验证行索引 (1~30)
    if(u2 < 0x01 || u2 > 0x1E) {
       // return -1;  // 无效行索引
    }
    
    // 转换为数组索引（0起始）
    int col = u1 - 1;    // 列索引：0~10
    int row = u2 - 1;    // 行索引：0~29
    
		AD9834_Select_Wave(Sine_Wave);
		AD9834_Set_Freq(FREQ_0, (row+1)*100);
    tv= table_data[row][col]+err;
		Dac1_Set_Vol(tv);
		
}
